package haggisworld;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.LinkedList;
import java.util.Observable;
import java.util.Observer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Andreas Miksik
 */
public class SpielServerThread extends Thread implements Observer {

    public static final int PORT = 50005;
    public int clientNr = 0;
    public static int clientNummer = 0;
    public SpielObjekt startobjekt;
    public Spiel spiel;
    ObjectInputStream input;
    ObjectOutputStream output;
    Socket socket = null;

    public SpielServerThread(Socket socket, int nr, SpielObjekt startobjekt, Spiel spiel) {
        this.clientNr = clientNummer + 1;
        this.socket = socket;
        this.startobjekt = startobjekt;
        this.spiel = spiel;
        spiel.addObserver(this);
        try {
            input = new ObjectInputStream(socket.getInputStream());
            output = new ObjectOutputStream(socket.getOutputStream());
        } catch (IOException ex) {
            Logger.getLogger(SpielServerThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Die run() Methode läuft, solange ein Thread ausgeführt wird. Der
     * ObjectOutputStream wartet und sendet Objekte.
     *
     */
    @Override
    public void run() {
        SpielObjekt objekt = null;
        System.out.println("Run() Methode läuft... AnzSpieler: " + SpielServer.getAnzSpieler());
        System.out.println("Fourth object in first list: " + startobjekt.getKarten(0).get(4));
        try {
            ++clientNummer;
            this.clientNr = clientNummer;

            output.writeObject(new SpielObjekt("C_NAME" + clientNummer));
            System.out.println("Klasse SpielServer - ClientNummer: " + clientNummer);

            boolean einMal = true;
            while ((SpielServer.getAnzSpieler() != 2)) {
                if (einMal) {
                    output.writeObject(new SpielObjekt("WARTE"));
                    einMal = false;
                }
                this.interrupt();
            }
            output.writeObject(new SpielObjekt("VERBUNDEN"));

            while ((objekt = (SpielObjekt) input.readObject()) != null) {
                System.out.println("ServerThread: Nachricht erhalten: " + objekt.getNachricht());
                spiel.erhalteSpielbefehl(objekt);
            }

        } catch (IOException ex) {
            Logger.getLogger(SpielServerThread.class.getName()).log(Level.SEVERE, null, ex);
            ex.printStackTrace();
            spiel.erhalteSpielbefehl(new SpielObjekt("VERBINDUNG_UNTERBROCHEN"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * Die Methode update() erhält Updates über das aktuelle Spielgeschehen.
     *
     * @param o Observable
     * @param arg Objekt mit aktuellem Spielgeschehen
     */
    @Override
    public void update(Observable o, Object arg) {
        SpielObjekt objekt = (SpielObjekt) arg;
        try {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
            output.writeObject(objekt);
            output.flush();
            output.reset();

            System.out.println("Client " + clientNr + ": Update Methode angewendet. Nachricht: " + objekt.getNachricht());
        } catch (IOException ex) {
            Logger.getLogger(SpielServerThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}
